package git.soulbgm.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import git.soulbgm.common.enums.Status;
import git.soulbgm.common.pojo.PageInfo;
import git.soulbgm.mapper.RoleMapper;
import git.soulbgm.mapper.UserRoleMapper;
import git.soulbgm.pojo.dto.RoleDto;
import git.soulbgm.pojo.entity.Role;
import git.soulbgm.pojo.entity.UserRole;
import git.soulbgm.service.MenuService;
import git.soulbgm.service.RoleService;
import git.soulbgm.utils.ModelBuilder;
import git.soulbgm.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;

/**
 * 角色相关业务逻辑
 *
 * @author SoulBGM
 * @date 2020-09-10 17:30:42
 */
@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private MenuService menuService;

    private Example getRoleExample(RoleDto role) {
        Example roleExample = new Example(Role.class);
        Example.Criteria criteria = roleExample.and();
        criteria.andEqualTo("delFlag", Status.EXIST.code);
        if (StringUtil.isNotEmpty(role.getRoleName())) {
            criteria.andLike("roleName", "%" + role.getRoleName() + "%");
        }
        if (StringUtil.isNotEmpty(role.getRoleCode())) {
            criteria.andLike("roleCode", "%" + role.getRoleCode() + "%");
        }
        if (role.getStatus() != null) {
            criteria.andEqualTo("status", role.getStatus());
        }
        if (role.getCreateStartTime() != null && role.getCreateEndTime() != null) {
            criteria.andBetween("createTime", role.getCreateStartTime(), role.getCreateEndTime());
        }
        return roleExample;
    }

    @Override
    public PageInfo find(Integer pageNum, Integer pageSize, RoleDto role) {
        PageHelper.startPage(pageNum, pageSize);
        Example roleExample = getRoleExample(role);
        List<Role> list = roleMapper.selectByExample(roleExample);
        return PageInfo.getPageInfo((Page) list);
    }

    @Override
    public Role findById(Long id) {
        Role role = roleMapper.selectByPrimaryKey(id);
        return role;
    }

    @Override
    public List<Long> findByRoleId(Long userId) {
        UserRole userRoleQueryParam = new UserRole();
        userRoleQueryParam.setUserId(userId);
        List<UserRole> userRoleList = userRoleMapper.select(userRoleQueryParam);
        List<Long> roleIdList = new ArrayList<>();
        for (UserRole userRole : userRoleList) {
            roleIdList.add(userRole.getRoleId());
        }
        return roleIdList;
    }

    @Override
    public Boolean addUserRole(Long userId, List<Long> roleIdList) {
        List<UserRole> userRoleList = new ArrayList<>(roleIdList.size());
        for (Long roleId : roleIdList) {
            UserRole userRole = new UserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            ModelBuilder.builder(userRole);
            userRoleList.add(userRole);
        }
        return userRoleMapper.insertList(userRoleList) == userRoleList.size();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Role add(Role role, List<Long> menuIdList) {
        int count = roleMapper.selectCount(Role.builder().roleCode(role.getRoleCode()).build());
        if (count > 0) {
            throw new RuntimeException("角色code已存在");
        }
        ModelBuilder.builder(role);
        int result = roleMapper.insertSelective(role);
        if (result > 0) {
            if (menuIdList != null && !menuIdList.isEmpty()) {
                menuService.addRoleMenu(role.getId(), menuIdList);
            }
            return role;
        } else {
            return null;
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean update(Role role, List<Long> menuIdList) {
        int result = roleMapper.updateByPrimaryKeySelective(role);
        if (result > 0) {
            if (menuIdList != null && !menuIdList.isEmpty()) {
                menuService.deleteRoleMenu(role.getId());
                menuService.addRoleMenu(role.getId(), menuIdList);
            }
            return true;
        }
        return false;
    }

    @Override
    public void deleteUserRole(Long userId) {
        Example example = new Example(UserRole.class);
        example.and().andEqualTo("userId", userId);
        int result = userRoleMapper.deleteByExample(example);
    }

    @Override
    public Boolean delete(List idList) {
        Example roleExample = new Example(Role.class);
        roleExample.and().andIn("id", idList);
        int result = roleMapper.deleteByExample(roleExample);
        return result > 0;
    }
}
